import numpy as np
import dash
from dash import dcc, html
from dash.dependencies import Input, Output, State
import plotly.graph_objects as go
from plotly.subplots import make_subplots


def get_matrices_component():
    component = html.Div([
        html.H3('矩阵运算可视化'),
        
        # 矩阵A输入
        html.Div([
            html.Label('矩阵A:'),
            html.Div([
                dcc.Input(id='a11', type='number', value=1, style={'width': '50px'}),
                dcc.Input(id='a12', type='number', value=2, style={'width': '50px'}),
                dcc.Input(id='a13', type='number', value=0, style={'width': '50px'}),
            ], style={'margin': '10px'}),
            html.Div([
                dcc.Input(id='a21', type='number', value=3, style={'width': '50px'}),
                dcc.Input(id='a22', type='number', value=4, style={'width': '50px'}),
                dcc.Input(id='a23', type='number', value=0, style={'width': '50px'}),
            ], style={'margin': '10px'}),
            html.Div([
                dcc.Input(id='a31', type='number', value=0, style={'width': '50px'}),
                dcc.Input(id='a32', type='number', value=0, style={'width': '50px'}),
                dcc.Input(id='a33', type='number', value=1, style={'width': '50px'}),
            ], style={'margin': '10px'}),
        ]),
        
        # 矩阵B输入
        html.Div([
            html.Label('矩阵B:'),
            html.Div([
                dcc.Input(id='b11', type='number', value=0, style={'width': '50px'}),
                dcc.Input(id='b12', type='number', value=1, style={'width': '50px'}),
                dcc.Input(id='b13', type='number', value=0, style={'width': '50px'}),
            ], style={'margin': '10px'}),
            html.Div([
                dcc.Input(id='b21', type='number', value=-1, style={'width': '50px'}),
                dcc.Input(id='b22', type='number', value=0, style={'width': '50px'}),
                dcc.Input(id='b23', type='number', value=0, style={'width': '50px'}),
            ], style={'margin': '10px'}),
            html.Div([
                dcc.Input(id='b31', type='number', value=0, style={'width': '50px'}),
                dcc.Input(id='b32', type='number', value=0, style={'width': '50px'}),
                dcc.Input(id='b33', type='number', value=1, style={'width': '50px'}),
            ], style={'margin': '10px'}),
        ]),
        
        # 结果显示
        dcc.Graph(id='matrices-plot', style={'width': '2024px', 'height': '1768px'}),
        html.Div(id='determinant-output'),
        html.Div(id='rank-output'),

         html.Div([
            html.P('提示：当输入矩阵的z值不为0时，将自动切换为3D显示模式'),
        ], style={'color': '#666', 'fontSize': '12px'}),
        
        # 数学原理与应用说明
        html.Div([
            html.H4('矩阵运算数学原理与应用'),
            
            html.Div([
                html.H5('矩阵加法'),
                html.P('• 数学家: Arthur Cayley (1821-1895) 首次系统研究矩阵运算'),
                html.P('• 原理: A + B = (a_ij + b_ij)'),
                html.P('• 应用: 计算机图形学中的坐标变换叠加、机器学习中的特征融合'),
            ], style={'marginBottom': '10px'}),
            
            html.Div([
                html.H5('矩阵乘法'),
                html.P('• 数学家: James Joseph Sylvester (1814-1897) 引入矩阵乘法概念'),
                html.P('• 原理: C = A·B，其中c_ij = Σ(a_ik * b_kj)'),
                html.P('• 应用: 神经网络中的权重计算、3D图形变换'),
            ], style={'marginBottom': '10px'}),
            
            html.Div([
                html.H5('行列式'),
                html.P('• 数学家: Gottfried Wilhelm Leibniz (1646-1716) 首次提出行列式概念'),
                html.P('• 原理: 表示线性变换对空间的缩放因子'),
                html.P('• 应用: 判断矩阵可逆性、计算变换后的体积变化'),
            ], style={'marginBottom': '10px'}),
            
            html.Div([
                html.H5('逆矩阵'),
                html.P('• 数学家: Carl Friedrich Gauss (1777-1855) 发展矩阵求逆方法'),
                html.P('• 原理: A·A⁻¹ = I，其中I是单位矩阵'),
                html.P('• 应用: 线性方程组求解、计算机视觉中的相机校准'),
            ], style={'marginBottom': '10px'}),
            
            html.Div([
                html.H5('矩阵的秩'),
                html.P('• 数学家: Georg Frobenius (1849-1917) 正式定义矩阵秩的概念'),
                html.P('• 原理: 矩阵中线性无关的行或列的最大数目'),
                html.P('• 应用: 判断线性方程组解的情况、机器学习中的特征选择'),
            ])
        ], style={'marginBottom': '20px', 'padding': '10px', 'border': '1px solid #ddd', 'borderRadius': '5px'})
    ])
    
    return component


def register_matrices_callbacks(app):
    @app.callback(
        [Output('matrices-plot', 'figure'),
         Output('determinant-output', 'children'),
         Output('rank-output', 'children')],
        [Input('a11', 'value'), Input('a12', 'value'), Input('a13', 'value'),
         Input('a21', 'value'), Input('a22', 'value'), Input('a23', 'value'),
         Input('a31', 'value'), Input('a32', 'value'), Input('a33', 'value'),
         Input('b11', 'value'), Input('b12', 'value'), Input('b13', 'value'),
         Input('b21', 'value'), Input('b22', 'value'), Input('b23', 'value'),
         Input('b31', 'value'), Input('b32', 'value'), Input('b33', 'value')]
    )
    def update_matrices(a11, a12, a13, a21, a22, a23, a31, a32, a33, b11, b12, b13, b21, b22, b23, b31, b32, b33):
        A = np.array([[a11, a12, a13], [a21, a22, a23], [a31, a32, a33]])
        B = np.array([[b11, b12, b13], [b21, b22, b23], [b31, b32, b33]])
        
        # 矩阵运算
        C_add = A + B  # 矩阵加法
        C_mul = np.dot(A, B)  # 矩阵乘法
        det_A = np.linalg.det(A)  # 行列式
        rank_A = np.linalg.matrix_rank(A)  # 矩阵秩
        try:
            A_inv = np.linalg.inv(A)  # 逆矩阵
        except np.linalg.LinAlgError:
            A_inv = np.zeros_like(A)
        
        # 创建多个子图
        fig = make_subplots(
            rows=2, cols=2,
            specs=[[{'type': 'surface'}, {'type': 'surface'}],
                   [{'type': 'surface'}, {'type': 'surface'}]],
            subplot_titles=('矩阵加法', '矩阵乘法', '行列式', '逆矩阵')
        )
        
        # 矩阵加法可视化
        fig.add_trace(go.Mesh3d(
            x=A[:,0], y=A[:,1], z=A[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='blue', opacity=0.5, name='矩阵A'
        ), row=1, col=1)
        fig.add_trace(go.Mesh3d(
            x=B[:,0], y=B[:,1], z=B[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='red', opacity=0.5, name='矩阵B'
        ), row=1, col=1)
        fig.add_trace(go.Mesh3d(
            x=C_add[:,0], y=C_add[:,1], z=C_add[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='green', opacity=0.5, name='矩阵和'
        ), row=1, col=1)
        
        # 矩阵乘法可视化
        fig.add_trace(go.Mesh3d(
            x=A[:,0], y=A[:,1], z=A[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='blue', opacity=0.5, name='矩阵A'
        ), row=1, col=2)
        fig.add_trace(go.Mesh3d(
            x=B[:,0], y=B[:,1], z=B[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='red', opacity=0.5, name='矩阵B'
        ), row=1, col=2)
        fig.add_trace(go.Mesh3d(
            x=C_mul[:,0], y=C_mul[:,1], z=C_mul[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='purple', opacity=0.5, name='矩阵积'
        ), row=1, col=2)
        
        # 行列式可视化
        fig.add_trace(go.Mesh3d(
            x=A[:,0], y=A[:,1], z=A[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='orange', opacity=0.5, name='矩阵A'
        ), row=2, col=1)
        
        # 逆矩阵可视化
        fig.add_trace(go.Mesh3d(
            x=A[:,0], y=A[:,1], z=A[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='blue', opacity=0.5, name='矩阵A'
        ), row=2, col=2)
        fig.add_trace(go.Mesh3d(
            x=A_inv[:,0], y=A_inv[:,1], z=A_inv[:,2],
            i=[0, 0, 1], j=[1, 2, 2], k=[2, 1, 0],
            color='cyan', opacity=0.5, name='逆矩阵'
        ), row=2, col=2)
        
        # 更新布局
        fig.update_layout(
            title_text='矩阵运算可视化',
            scene1=dict(
                xaxis=dict(title='X轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                yaxis=dict(title='Y轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                zaxis=dict(title='Z轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10)
            ),
            scene2=dict(
                xaxis=dict(title='X轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                yaxis=dict(title='Y轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                zaxis=dict(title='Z轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10)
            ),
            scene3=dict(
                xaxis=dict(title='X轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                yaxis=dict(title='Y轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                zaxis=dict(title='Z轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10)
            ),
            scene4=dict(
                xaxis=dict(title='X轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                yaxis=dict(title='Y轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10),
                zaxis=dict(title='Z轴', gridcolor='rgba(100, 100, 100, 0.8)', showbackground=True, backgroundcolor='rgba(230, 230, 230, 0.3)', gridwidth=2, showgrid=True, nticks=10)
            ),
            margin=dict(l=0, r=0, b=0, t=30),
            paper_bgcolor='white',
            plot_bgcolor='white'
        )
        
        return fig, f'矩阵A的行列式: {det_A:.2f}', f'矩阵秩: {rank_A}'